home *** CD-ROM | disk | FTP | other *** search
- /************************************************
- **
- ** *** HAPPy P-code Interpreter ***
- **
- ** P-code命令解釈実行処理
- **
- ** Copyright (c) H.Asano. 1992-1994.
- ************************************************/
-
- #define EXTERN extern
- #define trans(reg) \
- ((unsigned short)(reg)-(unsigned short)(store))/sizeof(_store)
-
- #define setlow 0
- #define sethigh 31
-
- #include <process.h>
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #include "hapai.h"
-
- extern void prerr(short,char*); /* Run-timeエラーメッセージ出力処理 */
- extern void puteoln(void) ; /* ファイルクローズ時のeoln付与処理 */
- extern void T_get(fileinfo*,_store*,char*); /* 1文字読込 */
- extern void EOL(void) ;
- extern void EoF(void) ;
- extern void GET(void) ;
- extern void PGE(void) ;
- extern void PUT(void) ;
- extern void RLN(void) ;
- extern void RDC(void) ;
- extern void RDI(void) ;
- extern void RDR(void) ;
- extern void RST(void) ;
- extern void RWT(void) ;
- extern void TGT(void) ;
- extern void TPT(void) ;
- extern void TRS(void) ;
- extern void TRW(void) ;
- extern void WLN(void) ;
- extern void WRB(void) ;
- extern void WRC(void) ;
- extern void WRF(void) ;
- extern void WRI(void) ;
- extern void WRR(void) ;
- extern void WRS(void) ;
-
- /**********************************************/
- /*** P-code 計算機のレジスタ、メモリその他 ***/
- /**********************************************/
-
- extern _store store[] ; /* 記憶装置 */
-
- extern _code cd ; /* p-code */
- extern _store *sp ; /* sp points to top of the stack */
-
- extern short pc ; /* program counter */
- extern short mp ; /* mp points to begginning of a data segment */
- extern short ep ; /* ep points to the maxmum extent of the stack */
- extern short np ; /* np points to top of the heap area */
- extern boolean trace ; /* 命令トレースフラグ */
- extern boolean readlnflag ; /* 起動時及びinputにreadlnをした時 真 */
-
- /******** Run Time Error Mesage(埋め込み要のもの) **********/
- static const struct {
- short errno ;
- char *msg ;
- } errtbl[] = {
- { 1, "配列の添え字式の値(%ld)が範囲内(%ld~%ld)にない"},
- { 7, "実値引数の値(%ld)が範囲内(%ld~%ld)にない"},
- { 8, "実値引数の集合値が範囲内(%ld~%ld)にない"},
- { 17, "read: バッファ変数の値(%d)が範囲内(%ld~%ld)にない"},
- { 18, "write: 式の値(%ld)が範囲内(%ld~%ld)にない"},
- { 26, "pack: 順序型の引数の値(%ld)が範囲内(%ld~%ld)にない"},
- { 29, "unpack: 順序型の引数の値(%ld)が範囲内(%ld~%ld)にない"},
- { 31, "unpack: 転送後に詰めなし配列の添え字型を越える"},
- { 38, "succ: 引数の順序数(%ld)より1つ大きい値が存在しない"},
- { 39, "pred: 引数の順序数(%ld)より1つ小さい値が存在しない"},
- { 49, "代入文: 右辺値(%ld)が範囲内(%ld~%ld)にない"},
- { 50, "代入文: 集合値が範囲内(%ld~%ld)にない"},
- { 51, "case文: 選択式の値(%ld)に合致する選択定数がない"},
- { 52, "for文: 初期値(%ld)が範囲内(%ld~%ld)にない"},
- { 53, "for文: 終値(%ld)が範囲内(%ld~%ld)にない"},
- { 71, "read: 集合型のバッファ変数の値が範囲内(%ld~%ld)にない"},
- { 72, "write: 集合型の式の値が範囲内(%ld~%ld)にない"},
- {111, "集合構成子の順序式の値(%ld)がHAPPyの制限範囲内(%ld~%ld)にない"}
- } ;
-
- /***************************************/
- /* base() : 局所的番地を求める */
- /***************************************/
- static short base(void)
- {
- short ad ;
- short ld ;
-
- if(cd.p==0) return(mp) ; /* pが0ならmp値を返す */
- ad = mp ;
- ld = cd.p ;
- while((ld--)) /* 0より大きい間繰り返し */
- ad = store[ad+1].va ; /* static link */
- return(ad) ;
- }
-
- /***************************************/
- /* StrComp() : 文字列の比較を行う */
- /***************************************/
- static short StrComp(_store *str1,_store *str2,short length)
- {
- register _store *s1,*s2 ;
- short disp ;
-
- s1 = str1 ;
- s2 = str2 ;
- while(length--) {
- disp = s1++->vc - s2++->vc ;
- if(disp) return(disp) ;
- }
- return(0) ; /* s1とs2が同じ */
- }
-
- /************************ 各P-code の 処理 ****************************/
-
- /******************/
- /* ABI */ /* absolute integers */
- /******************/
- static void ABI(void)
- {
- (*sp).vi = labs((*sp).vi) ;
- }
-
- /******************/
- /* ABR */ /* absolute reals */
- /******************/
- static void ABR(void)
- {
- (*sp).vr = (float)fabs((double)(*sp).vr);
- }
-
- /******************/
- /* ADI */ /* add integers */
- /******************/
- static void ADI(void)
- {
- sp->vi += (sp--)->vi ;
- }
-
- /******************/
- /* ADR */ /* add reals */
- /******************/
- static void ADR(void)
- {
- sp-- ;
- (*sp).vr += (*(sp+1)).vr ;
- }
-
- /******************/
- /* AND */ /* logical and */
- /******************/
- static void AND(void)
- {
- sp-- ;
- (*sp).vb = (*sp).vb && (*(sp+1)).vb ;
- }
-
- /**************************************/
- /* ATN() : arctan標準関数 */
- /**************************************/
- static void ATN(void)
- {
- (*sp).vr = (float)atan((double)(*sp).vr);
- }
-
- /******************/
- /* BAS */ /* load base mark */
- /******************/
- static void BAS(void)
- {
- (*++sp).va = base() ;
- }
-
- /*****************/
- /* CHK */
- /*****************/
- static void CHK(void)
- {
- short i ;
- char buf[80] ;
-
- if(((*sp).vi < store[cd.q-1].vi) ||
- ((*sp).vi > store[cd.q].vi)) {
- i = -1 ;
- while(errtbl[++i].errno != cd.p) ;
- sprintf(buf,errtbl[i].msg,
- (*sp).vi, store[cd.q-1].vi,store[cd.q].vi) ;
- prerr(cd.p,buf) ; /* エラーメッセージ出力 */
- }
- }
-
- /******************/
- /* CHKs */ /* check set */
- /******************/
- static void CHKs(void)
- {
- short i ;
- long s = 0 ; /* 集合 */
- char buf[80] ;
-
- for(i=(short)store[cd.q-1].vi;i<=(short)store[cd.q].vi;i++)
- addset(s,i);
- s = (~s & (*sp).vs) ;
- if(s != 0) {
- i = -1 ;
- while(errtbl[++i].errno != cd.p) ;
- sprintf(buf,errtbl[i].msg,
- store[cd.q-1].vi,store[cd.q].vi) ;
- prerr(cd.p,buf) ; /* エラーメッセージ出力 */
- }
- }
-
- /******************/
- /* CHR */ /* convert character */
- /******************/
- static void CHR(void)
- {
- char buf[80] ;
-
- if(((*sp).vi < 0L) || (255L < (*sp).vi)) {
- sprintf(buf,"chr: 引数の値(%ld)に対応する文字がない",(*sp).vi);
- prerr(9,buf) ;
- }
- /* integer と char エリアは 0~255の範囲では同一なので変換不要 */
- }
-
- /******************/
- /* CKA */ /* Check Address */
- /******************/
- static void CKA(void)
- {
- if((*sp).va == NilValue)
- prerr(3,"対象変数のポインタ変数の値がnilである") ;
-
- if(!((np <= (*sp).va) && ((*sp).va < Maxstore)))
- prerr(4,"対象変数のポインタ変数の値が不定である") ;
- }
-
- /**************************************/
- /* COS() : cos標準関数 */
- /**************************************/
- static void COS(void)
- {
- (*sp).vr = (float)cos((double)(*sp).vr) ;
- }
-
- /******************/
- /* CUI */ /* Call User procedure Indirect */
- /******************/
- static void CUI(void)
- {
- short calladr ;
-
- calladr = (*sp--).va ; /* 実行開始アドレス取得 */
- mp= trans(sp) - (cd.p+4) ; /* 4はmstと関係 */
- store[mp+4].va = pc ; /* 戻り番地 */
- pc = calladr ; /* jump */
- }
-
- /******************/
- /* CUP */ /* Call User Procedure */
- /******************/
- static void CUP(void)
- {
- mp =trans(sp) - (cd.p+4) ; /* 4はmstと関係*/
- store[mp+4].va = pc ; /* 戻り番地 */
- pc = cd.q ; /* jump */
- }
-
- /******************/
- /* DEC */
- /******************/
- static void DEC(void)
- {
- if(cd.p==1) (*sp).vi -= cd.q ; /* 1(i) */
- else (*sp).vc -= cd.q ; /* 0(a) 3(b) 6(c) */
- /* ↑ boolean,char,addressエリアは同一 */
- }
-
- /******************/
- /* DIF */
- /******************/
- static void DIF(void)
- {
- sp--;
- (*sp).vs &= ((*sp).vs ^ (*(sp+1)).vs) ;
- }
-
- /**************************************/
- /* DIS() : dispose標準手続き */
- /**************************************/
- static void DIS(void)
- {
- short ad ;
-
- ad = (*sp--).va ; /* 解放するアドレス */
- if(ad == NilValue)
- prerr(23,"dispose: 引数の値がnilである") ;
- if((np <= ad) && (ad < Maxstore)) { /* 正常値 */
- if(ad == np) np += cd.q ; /* 一番後にnewした時だけ*/
- /* 本当に解放する */
- }
- else prerr(24,"dispose: 引数の値が不定である") ;
- }
-
- /******************/
- /* DVI */
- /******************/
- static void DVI(void)
- {
- if((*sp--).vi == 0) prerr(45,"div演算子: 0で割ろうとしている") ;
- (*sp).vi /= (*(sp+1)).vi ;
- }
-
- /******************/
- /* DVR */
- /******************/
- static void DVR(void)
- {
- if((*sp--).vr == (float)0.0)
- prerr(44,"/演算子: 0で割ろうとしている") ;
- (*sp).vr /= (*(sp+1)).vr ;
- }
-
- /******************/
- /* EJP */ /* Extra block Jump */
- /******************/
- static void EJP(void)
- {
- short req ;
-
- req = base() ;
- while(mp != req) { /* スタックの枠を解放 */
- sp = store + mp - 1 ;
- ep = store[mp+3].va ; /* mp+3 ・・・ 旧ep */
- mp = store[mp+2].va ; /* mp+2 ・・・ 動鎖 */
- }
- pc = cd.q;
- }
-
- /******************/
- /* ENT */
- /******************/
- static void ENT(void)
- {
- sp = store + mp + cd.q - 1 ; /* スタックポインタ設定 */
- if((ep = trans(sp)+cd.p) >= np) /* スタックの枠限界設定
- & スタックチェック */
- prerr(122,"スタック用のメモリが不足している") ;
- }
-
- /******************/
- /* EQU */
- /******************/
- static void EQU(void)
- {
- sp-- ;
-
- switch(cd.p) {
- case 1: /* (*sp).vb = (*sp).vi == (*(sp+1)).vi ; return; */
- case 2: /* (*sp).vb = (*sp).vr == (*(sp+1)).vr ; return; */
- case 4: (*sp).vb = (*sp).vs == (*(sp+1)).vs ; return;
-
- case 6: /* (*sp).vb = (*sp).vc == (*(sp+1)).vc ; return; */
- case 0: /* (*sp).vb = (*sp).va == (*(sp+1)).va ; return; */
- case 3: (*sp).vb = (*sp).vb == (*(sp+1)).vb ; return;
-
- case 5: (*sp).vb = (StrComp(store+(*sp).va,
- store+(*(sp+1)).va,
- cd.q) == 0);
- }
- }
-
- /**************************************/
- /* EXP() : exp標準関数 */
- /**************************************/
- static void EXP(void)
- {
- (*sp).vr = (float)exp((double)(*sp).vr) ;
- }
-
- /******************/
- /* FJP */
- /******************/
- static void FJP(void)
- {
- if(! (*(sp--)).vb) pc = cd.q;
- }
-
- /******************/
- /* FLO */
- /******************/
- static void FLO(void)
- {
- (*(sp-1)).vr = (float)(*(sp-1)).vi ;
- }
-
- /******************/
- /* FLT */
- /******************/
- static void FLT(void)
- {
- (*sp).vr = (float)(*sp).vi ;
- }
-
- /******************/
- /* GEQ */
- /******************/
- static void GEQ(void)
- {
- sp-- ;
- switch(cd.p) {
- case 1: (*sp).vb = (*sp).vi >= (*(sp+1)).vi ; return;
-
- case 2: (*sp).vb = (*sp).vr >= (*(sp+1)).vr ; return;
-
- case 6: /* (*sp).vb = (*sp).vc >= (*(sp+1)).vc ; return; */
- case 3: (*sp).vb = (*sp).vb >= (*(sp+1)).vb ; return;
-
- case 4: (*sp).vb = !
- ((*(sp+1)).vs & ((*(sp+1)).vs ^ (*sp).vs)) ; return;
-
- case 5: (*sp).vb = (StrComp(store+(*sp).va,
- store+(*(sp+1)).va,
- cd.q) >= 0);
- }
- }
-
- /******************/
- /* GRT */
- /******************/
- static void GRT(void)
- {
- sp-- ;
- switch(cd.p) {
- case 1: (*sp).vb = (*sp).vi > (*(sp+1)).vi ; return;
-
- case 6: /* (*sp).vb = (*sp).vc > (*(sp+1)).vc ; return; */
- case 3: (*sp).vb = (*sp).vb > (*(sp+1)).vb ; return;
-
- case 2: (*sp).vb = (*sp).vr > (*(sp+1)).vr ; return;
-
- case 5: (*sp).vb = (StrComp(store+(*sp).va,
- store+(*(sp+1)).va,
- cd.q) > 0);
- }
- }
-
- /******************/
- /* INC */
- /******************/
- static void INC(void)
- {
- if(cd.p==1) (*sp).vi += cd.q ; /* 1(i) */
- else (*sp).vc += cd.q ; /* 0(a) 3(b) 6(c) */
- /* ↑ boolean,char,addressエリアは同一 */
- }
-
- /******************/
- /* IND */ /* INDirect */
- /******************/
- static void IND(void)
- {
- (*sp)=store[(*sp).va+cd.q] ;
- }
-
- /******************/
- /* INDa */ /* INDirect address */
- /******************/
- static void INDa(void)
- {
- (*sp).va=store[(*sp).va+cd.q].va ;
- }
-
- #define INDb INDa
- #define INDs IND
- #define INDr IND
-
- /******************/
- /* INDc */ /* INDirect character */
- /******************/
- /* inputバッファの値が決まっていない時のために
- 特別な処理が必要なので、この処理を作りました */
- static void INDc(void)
- {
- short adr ;
-
- adr = (*sp).va+cd.q ;
- if((adr == fi[0].fileadr) && readlnflag) {
- T_get(fi,store+adr,"get");
- readlnflag = false ;
- }
-
- (*sp).vc = store[adr].vc ;
- }
-
- /******************/
- /* INN */
- /******************/
- static void INN(void)
- {
- integer i;
-
- i=(*(--sp)).vi ;
- (*sp).vb =
- (i & 0xffffffe0) /* 0<=i<=31 かどうかの判定 */
- ? (boolean)false
- : (boolean)(((*(sp+1)).vs >> (char)i) & 0x1) ;
- }
-
- /******************/
- /* INT */
- /******************/
- static void INT(void)
- {
- sp--;
- (*sp).vs &= (*(sp+1)).vs ;
- }
-
- /******************/
- /* IOR */ /* logical inclusive or */
- /******************/
- static void IOR(void)
- {
- sp-- ;
- (*sp).vb = (*sp).vb || (*(sp+1)).vb ;
- }
-
- /******************/
- /* IXA */
- /******************/
- static void IXA(void)
- {
- short disp ;
-
- disp = (short)((*sp--).vi - store[cd.q-1].vi);/* 配列の下限値を引く*/
- (*sp).va += store[cd.q].va * disp ;
- /* ↑ vaは2バイトエリアとて使用 */
- }
-
- /******************/
- /* LAO */ /* load base-level address */
- /******************/
- static void LAO(void)
- {
- (*(++sp)).va = cd.q ;
- }
-
- /******************/
- /* LAP */ /* Load Address Procedure */
- /******************/
- #define LAP LAO
-
- /******************/
- /* LCA */
- /******************/
- #define LCA LAO
-
- /******************/
- /* LCI */ /* load constant integer */
- /******************/
- #define LCI LDO
-
- /******************/
- /* LDA */ /* load level p address */
- /******************/
- static void LDA(void)
- {
- (*(++sp)).va = base()+cd.q ;
- }
-
- /******************/
- /* LDC */ /* load constant */
- /******************/
- static void LDC(void)
- {
- sp++ ;
- switch(cd.p) {
- case 1 : (*sp).vi = cd.q; return ; /* integer */
-
- case 6 : /* (*sp).vc = cd.q; return ; */ /* char */
- case 3 : (*sp).vb = cd.q; return ; /* boolean */
-
- case 2 : /* (*sp).vr = store[cd.q].vr; return;*//* real */
- case 4 : *sp = store[cd.q]; return; /* set */
-
- case 0 : (*sp).va = NilValue ; /* nil */
- /* programmer が 生成できない値 */
- }
- }
-
- /******************/
- /* LDO */ /* load contents of base-level address */
- /******************/
- static void LDO(void)
- {
- *(++sp)=store[cd.q] ;
- }
-
- /******************/
- /* LDOc */ /* load char of base-level address */
- /******************/
- /* inputバッファの値が決まっていない時のために
- 特別な処理が必要なので、この処理を作りました */
- static void LDOc(void)
- {
- if((cd.q == fi[0].fileadr) && readlnflag) {
- T_get(fi,store+cd.q,"get");
- readlnflag = false ;
- }
-
- (*(++sp)).vc = store[cd.q].vc ;
- }
-
- /******************/
- /* LDOa */ /* load char of base-level address */
- /******************/
- static void LDOa(void)
- {
- (*(++sp)).va = store[cd.q].va ;
- }
-
- #define LDOb LDOa
- #define LDOr LDO
- #define LDOs LDO
-
- /******************/
- /* LEQ */
- /******************/
- static void LEQ(void)
- {
- sp-- ;
- switch(cd.p) {
- case 1: (*sp).vb = (*sp).vi <= (*(sp+1)).vi ; return;
-
- case 2: (*sp).vb = (*sp).vr <= (*(sp+1)).vr ; return;
-
- case 6: /* (*sp).vb = (*sp).vc <= (*(sp+1)).vc ; return; */
- case 3: (*sp).vb = (*sp).vb <= (*(sp+1)).vb ; return;
-
- case 4: (*sp).vb = !
- ((*sp).vs & ((*sp).vs ^ (*(sp+1)).vs)) ; return;
-
- case 5: (*sp).vb = (StrComp(store+(*sp).va,
- store+(*(sp+1)).va,
- cd.q) <= 0);
- }
- }
-
- /******************/
- /* LES */
- /******************/
- static void LES(void)
- {
- sp-- ;
- switch(cd.p) {
- case 1: (*sp).vb = (*sp).vi < (*(sp+1)).vi ; return;
-
- case 2: (*sp).vb = (*sp).vr < (*(sp+1)).vr ; return;
-
- case 6: /* (*sp).vb = (*sp).vc < (*(sp+1)).vc ; return; */
- case 3: (*sp).vb = (*sp).vb < (*(sp+1)).vb ; return;
-
- case 5: (*sp).vb = (StrComp(store+(*sp).va,
- store+(*(sp+1)).va,
- cd.q) < 0);
- }
- }
-
- /******************/
- /* LOD */ /* load contents of address at level p */
- /******************/
- static void LOD(void)
- {
- *(++sp) = store[base()+cd.q] ;
- }
-
- /******************/
- /* LODa */ /* load contents of address at level p */
- /******************/
- static void LODa(void)
- {
- (*(++sp)).va = store[base()+cd.q].va ;
- }
-
- #define LODc LODa
- #define LODb LODa
- #define LODs LOD
- #define LODr LOD
-
- /**************************************/
- /* LOG() : ln標準関数 */
- /**************************************/
- static void LOG(void)
- {
- if((*sp).vr <= (float)0.0)
- prerr(33,"ln: 引数の値が0以下である") ;
- (*sp).vr = (float)log((double)(*sp).vr);
- }
-
- /******************/
- /* MMS */ /* Make Multiple Set */
- /******************/
- /* この命令だけが -dオプション指定時 自前でチェックを行っている。
- 統一がとれていないけど 暫定的処置である */
-
- static void MMS(void)
- {
- long s = 0;
- short i ;
- long low,high ; /* 下限 上限 */
- char buf[80] ;
-
- sp-- ;
- if(cd.p<=1) { /* p in [0,1] */
- low = sp->vi ;
- high = (sp+1)->vi ;
- }
- else { /* p in [2,3] */
- low = (sp+1)->vi ;
- high = sp->vi ;
- }
- if(cd.p & 0x1) /* p in [1,3] (-dオプション) */
- if((low <= high) && /* 下限の方が大きい・・・要素なし*/
- (((long)setlow > low) || (high > (long)sethigh))) {
- sprintf(buf,
- "集合: 式..式の値ががHAPPyの制限範囲内(%d~%d)にない",
- setlow,sethigh) ;
- prerr(112,buf) ; /* エラーメッセージ出力 */
- }
- for(i=(short)low;i<=(short)high;i++) addset(s,(short)i);
- (*sp).vs = s;
- }
-
- /******************/
- /* MOD */
- /******************/
- static void MOD(void)
- {
- if((*sp--).vi <= 0)
- prerr(46,"mod演算子: 右辺値が0または負である") ;
- (*sp).vi %= (*(sp+1)).vi ;
- }
-
- /******************/
- /* MOV */
- /******************/
- static void MOV(void)
- {
- if(cd.p==1) /* 通常 */
- memcpy(store+(sp-1)->va,
- store+sp->va, cd.q*sizeof(_store)) ;
- else /* cd.p==2 */ /* pack,unpack,writeの時使う */
- memcpy(store+sp->va,
- store+(sp-1)->va, cd.q*sizeof(_store)) ;
-
- sp-=2 ;
-
- }
-
- /******************/
- /* MPI */
- /******************/
- static void MPI(void)
- {
- sp--;
- (*sp).vi *= (*(sp+1)).vi ;
- }
-
- /******************/
- /* MPR */
- /******************/
- static void MPR(void)
- {
- sp--;
- (*sp).vr *= (*(sp+1)).vr ;
- }
-
- /******************/
- /* MSI */ /* Mark Stack Indirect */
- /******************/
- static void MSI(void)
- {
- (*(sp+2)).va = (*(sp--)).va ; /* 静鎖 */
- (*(sp+3)).va = mp ; /* 動鎖 */
- (*(sp+4)).va = ep ; /* 旧ep */
- sp += 5 ;
- }
-
- /******************/
- /* MST */ /* Mark STack */
- /******************/
- static void MST(void)
- {
- (*(sp+2)).va = base() ; /* 静鎖 */
- (*(sp+3)).va = mp ; /* 動鎖 */
- (*(sp+4)).va = ep ; /* 旧ep */
- sp += 5 ;
- }
-
- /******************/
- /* NEQ */
- /******************/
- static void NEQ(void)
- {
- sp-- ;
- switch(cd.p) {
- case 1: /* (*sp).vb = (*sp).vi != (*(sp+1)).vi ; return; */
- case 2: /* (*sp).vb = (*sp).vr != (*(sp+1)).vr ; return; */
- case 4: (*sp).vb = (*sp).vs != (*(sp+1)).vs ; return;
-
- case 0: /* (*sp).vb = (*sp).va != (*(sp+1)).va ; return; */
- case 6: /* (*sp).vb = (*sp).vc != (*(sp+1)).vc ; return; */
- case 3: (*sp).vb = (*sp).vb != (*(sp+1)).vb ; return;
-
- case 5: (*sp).vb = (StrComp(store+(*sp).va,
- store+(*(sp+1)).va,
- cd.q) != 0);
- }
- }
-
- /**************************************/
- /* NEW() : new標準手続き */
- /**************************************/
- static void NEW(void)
- {
- short ad ;
-
- np -= cd.q ;
- if(np <= ep)
- prerr(121,"new: メモリ不足で割り付けができない") ;
- ad = (*sp--).va ;
- store[ad].va = np ;
- }
-
- /******************/
- /* NGI */
- /******************/
- static void NGI(void)
- {
- (*sp).vi = - (*sp).vi ;
- }
-
- /******************/
- /* NGR */
- /******************/
- static void NGR(void)
- {
- (*sp).vr = - (*sp).vr ;
- }
-
- /******************/
- /* NOT */
- /******************/
- static void NOT(void)
- {
- (*sp).vb = ! (*sp).vb ;
- }
-
- /******************/
- /* NXT */ /* next */ /* for ~ to */
- /******************/
- static void NXT(void)
- {
- if(cd.p==1) store[mp+cd.q].vi++ ;
- else store[mp+cd.q].vc++ ; /* 3(b) 6(c) */
- /* ↑ char と boolean は 同じエリア */
- }
-
- /******************/
- /* NXD */ /* next downto */ /* for ~ downto */
- /******************/
- static void NXD(void)
- {
- if(cd.p==1) store[mp+cd.q].vi-- ;
- else store[mp+cd.q].vc-- ; /* 3(b) 6(c) */
- /* ↑ char と boolean は 同じエリア */
- }
-
- /******************/
- /* ODD */
- /******************/
- static void ODD(void)
- {
- (*sp).vb = (boolean)((*sp).vi & 0x00000001) ;
- }
-
- /******************/
- /* ORD */ /* ORDinary */
- /******************/
- static void ORD(void)
- {
- /* vc も vb も同じエリアなのでif文不要 */
- /*if(cd.p == 3)*/ /* ordb */
- (*sp).vi = (integer)(*sp).vb ;
- /*else*/ /* ordc */
- /*(*sp).vi = (integer)(*sp).vc ;*/
- }
-
- /******************/
- /* RET */
- /******************/
- static void RET(void)
- {
- if(cd.p==0) sp = store + mp -1 ; /* retp:p=0 p<>0は以下の命令 */
- else sp = store + mp ; /* reti,retr,retc,retb,rets */
- pc = store[mp+4].va ; /* pc 復帰 */
- ep = store[mp+3].va ; /* ep 復帰 */
- mp = store[mp+2].va ; /* mp 復帰 */
- }
-
- /******************/
- /* ROU */ /* round */
- /******************/
- static void ROU(void)
- {
- (*sp).vi = (integer)floor((double)((*sp).vr + 0.5)) ;
- }
-
- /******************/
- /* SBI */ /* subtruct integers */
- /******************/
- static void SBI(void)
- {
- sp->vi -= (sp--)->vi ;
- }
-
- /******************/
- /* SBR */ /* subtruct reals */
- /******************/
- static void SBR(void)
- {
- sp-- ;
- (*sp).vr -= (*(sp+1)).vr ;
- }
-
- /******************/
- /* SGS */
- /******************/
- static void SGS(void)
- {
- long s = 0 ;
-
- addset(s,(short)(*sp).vi) ;
- (*sp).vs = s ;
- }
-
- /***************************************/
- /* SIN() : sin標準関数 */
- /***************************************/
- static void SIN(void)
- {
- (*sp).vr = (float)sin((double)(*sp).vr) ;
- }
-
- /******************/
- /* SQI */
- /******************/
- static void SQI(void)
- {
- (*sp).vi *= (*sp).vi ;
- }
-
- /******************/
- /* SQR */
- /******************/
- static void SQR(void)
- {
- (*sp).vr *= (*sp).vr ;
- }
-
- /***************************************/
- /* SQT() : sqrt標準関数 */
- /***************************************/
- static void SQT(void)
- {
- if((*sp).vr < (float)0.0) /* 負の平方根 */
- prerr(34,"sqrt:引数の値が負である") ;
- (*sp).vr = (float)sqrt((double)(*sp).vr);
- }
-
- /******************/
- /* SRO */ /* store at base-level address */
- /******************/
- static void SRO(void)
- {
- store[cd.q] = *(sp--) ;
- }
-
- /******************/
- /* SROa */ /* store at base-level address */
- /******************/
- static void SROa(void)
- {
- store[cd.q].va = (*(sp--)).va ;
- }
-
- #define SROc SROa
- #define SROb SROa
- #define SROr SRO
- #define SROs SRO
-
- /******************/
- /* STO */
- /******************/
- static void STO(void)
- {
- store[(*(sp-1)).va] = *sp ;
- sp-=2 ;
- }
-
- /******************/
- /* STOa */
- /******************/
- static void STOa(void)
- {
- store[(*(sp-1)).va].va = (*sp).va ;
- sp-=2 ;
- }
-
- #define STOc STOa
- #define STOb STOa
- #define STOr STO
- #define STOs STO
-
- /******************/
- /* STP */ /* stop */
- /******************/
- static void STP(void)
- {
- puteoln() ; /* ファイルクローズ & eoln付与*/
- exit(0) ;
- }
-
- /******************/
- /* STR */ /* store contents at address at level p */
- /******************/
- static void STR(void)
- {
- store[base()+cd.q] = *sp-- ;
- }
-
- /******************/
- /* STRa */ /* store contents at address at level p */
- /******************/
- static void STRa(void)
- {
- store[base()+cd.q].va = (*(sp--)).va ;
- }
-
- #define STRc STRa
- #define STRb STRa
- #define STRr STR
- #define STRs STR
-
-
- /******************/
- /* TRA */ /* trace of execuction */
- /******************/
- static void TRA(void)
- {
- trace = (cd.p==1) ; /* tra 1 の時 トレースON */
- }
-
- /******************/
- /* TRC */ /* truncate */
- /******************/
- static void TRC(void)
- {
- (*sp).vi = (integer)(*sp).vr ;
- }
-
- /******************/
- /* UDF */ /* UnDeFined instruction */
- /******************/
- static void UDF(void)
- {
- prerr(142,"未定義命令を実行しようとした") ;
- }
-
- /******************/
- /* UJC */
- /******************/
- static void UJC(void)
- {
- prerr(51,"case文: 選択式の値に合致する選択定数がない") ;
- }
-
- /******************/
- /* UJP */
- /******************/
- static void UJP(void)
- {
- pc = cd.q;
- }
-
- /******************/
- /* UNI */
- /******************/
- static void UNI(void)
- {
- sp-- ;
- (*sp).vs |= (*(sp+1)).vs ;
- }
-
- /******************/
- /* XJP */
- /******************/
- static void XJP(void)
- {
- pc += (short)(*sp--).vi ;
- }
-
- /**********************************************************************/
- /* P-code 別 処理エントリ表 */
- /**********************************************************************/
-
- static struct entry {
- void (*func)(void) ;
- } pcd[] = {
- /* xx0 xx1 xx2 xx3 xx4 xx5 xx6 xx7 xx8 xx9 */
- /*00x*/ LOD, LDO, STR, SRO, STO, CHK, IND, LDC, LDA, DEC,
- /*01x*/ INC, MST, CUP, ENT, RET, UDF, IXA, EQU, NEQ, GEQ,
- /*02x*/ GRT, LEQ, LES, UJP, FJP, XJP, EJP, LAP, ADI, ADR,
- /*03x*/ SBI, SBR, SGS, FLT, FLO, TRC, NGI, NGR, SQI, SQR,
- /*04x*/ ABI, ABR, NOT, AND, IOR, DIF, INT, UNI, INN, MOD,
- /*05x*/ ODD, MPI, MPR, DVI, DVR, MOV, LCA, LAO, STP, ORD,
- /*06x*/ CHR, UJC, MMS, MSI, CUI, BAS, LCI, CKA, TRA, ROU,
- /*07x*/ NXT, NXD, UDF, UDF, UDF, NEW, DIS, PGE, EoF, EOL,
- /*08x*/ RST, RWT, GET, PUT, WRS, WRB, WRI, WRR, WRC, WRF,
- /*09x*/ WLN, RDI, RDR, RDC, RLN, TRS, TRW, TGT, TPT, ATN,
- /*10x*/ SIN, COS, EXP, LOG, SQT, LDOa,LDOr,LDOs,LDOb,LDOc,
- /*11x*/ UDF, UDF, CHKs,CHK, CHK, LODa,LODr,LODs,LODb,LODc,
- /*12x*/ SROa,SROr,SROs,SROb,SROc,STRa,STRr,STRs,STRb,STRc,
- /*13x*/ STOa,STOr,STOs,STOb,STOc,INDa,INDr,INDs,INDb,INDc,
- /*14x*/ UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
- /*15x*/ UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
- /*16x*/ UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
- /*17x*/ UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
- /*18x*/ UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
- /*19x*/ UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
- /*20x*/ UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
- /*21x*/ UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
- /*22x*/ UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
- /*23x*/ UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
- /*24x*/ UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF, UDF,
- /*25x*/ UDF, UDF, UDF, UDF, UDF, UDF
- };
-
- /***********************/
- /* トレース処理 */
- /***********************/
- static void tracing(void)
- {
- printf("%4d[%3d %1d %6d] mp=%4d ep=%4d np=%4d stack[%4d]=%08lxH\n",
- pc-1,cd.op,cd.p,cd.q, mp,ep,np,trans(sp),(*sp).vi);
- }
-
- /********************************/
- /* P-code の 解釈実行処理 */
- /********************************/
- void interpret(void)
- {
- loop:
- cd = store[pc++].vo ;
-
- if(trace) tracing() ; /* トレースオプション有効 */
-
- pcd[cd.op].func() ; /* opに対応した命令を実行 */
-
- goto loop;
- }